package com.ruoyi.web.controller.system;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.CommonEntity;
import com.ruoyi.common.core.page.PageQuery;
import com.ruoyi.common.core.page.PageUtil;
import com.ruoyi.common.core.page.ResultEntity;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.MaterialHistoryService;
import com.ruoyi.system.service.MaterialLogService;
import com.ruoyi.system.service.MaterialService;

import com.ruoyi.system.service.MaterialReportService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Api(tags = "物料管理")
@RestController
@RequestMapping("/material")
public class MaterialController {
    @Autowired
    private MaterialService materialService;


    @Autowired
    private MaterialLogService materialLogService;

    @Autowired
    private MaterialReportService materialReportService;


    @Autowired
    private MaterialHistoryService materialHistoryService;


    /*
     *  1.判断数量是否满足出库
     *  2. 减少数量
     *  添加出库记录
     * */
    @PostMapping("/in/add")
    @ApiOperation(value = "材料入库")
    @Transactional
    public ResultEntity addIn(@RequestBody MaterialLogEntity params){
        var materialId = params.getMaterialId();
        var materialEntity = materialService.getById(materialId);
        materialEntity.setNum(materialEntity.getNum() + params.getNum());
        materialEntity.setInTotal(materialEntity.getInTotal() + params.getNum());
        materialService.saveOrUpdate(materialEntity);
        params.setCreateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setUpdateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setCreator(SecurityUtils.getLoginUser().getUser().getName());
        params.setIsIn(1);  //todo 改成全局变量
        materialLogService.saveOrUpdate(params);
        return ResultEntity.createSuccess();
    }


    @GetMapping("/in/list")
    @ApiOperation(value = "获取入库记录表")
    public ResultEntity listIn(PageQuery pageQuery){
        PageUtil.startPage(pageQuery);
        return ResultEntity.createSuccess(PageUtil.getPageList(materialLogService.list(new LambdaQueryWrapper<MaterialLogEntity>()
                .eq(MaterialLogEntity::getDelFlag,0)
                .eq(MaterialLogEntity::getIsIn, 1)
                .orderByDesc(CommonEntity::getUpdateTime))));
    }

    @GetMapping("/log/list")
    @ApiOperation(value = "所有的日志记录")
    public ResultEntity listLog(PageQuery pageQuery){
        PageUtil.startPage(pageQuery);
        return ResultEntity.createSuccess(PageUtil.getPageList(materialLogService.list(new LambdaQueryWrapper<MaterialLogEntity>()
                .eq(MaterialLogEntity::getDelFlag,0)
                .orderByDesc(CommonEntity::getUpdateTime))));
    }


    @PostMapping("/out/add")
    @ApiOperation(value = "添加出库记录")
    /*
     *  1.判断数量是否满足出库
     *  2. 减少数量
     *  添加出库记录
     * */
    public ResultEntity addOut(@RequestBody MaterialLogEntity params){
        var materialId = params.getMaterialId();
        var materialNum = materialService.getById(materialId).getNum();

        if (materialNum < params.getNum()) {
            return ResultEntity.createError("-1","出库数量大于库存数量");
        }
        var materialEntity = materialService.getById(materialId);
        materialEntity.setNum(materialEntity.getNum() - params.getNum());
        materialService.saveOrUpdate(materialEntity);

        params.setCreateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setUpdateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setCreator(SecurityUtils.getLoginUser().getUser().getName());
        params.setIsIn(2);  //todo 改成全局变量
        materialLogService.saveOrUpdate(params);
        return ResultEntity.createSuccess();
    }

    @GetMapping("/out/list")
    @ApiOperation(value = "获取出库记录表")
    public ResultEntity listOut(PageQuery pageQuery){
        PageUtil.startPage(pageQuery);
        return ResultEntity.createSuccess(PageUtil.getPageList(materialLogService.list(new LambdaQueryWrapper<MaterialLogEntity>()
                .eq(MaterialLogEntity::getDelFlag,0)
                .orderByDesc(CommonEntity::getUpdateTime))));
    }

    @GetMapping("/in/chart")
    @ApiOperation(value = "每天库存量图")
    /*
        1. 获取 material_history_tab 中
        2. 再加上当天的数据数据量
        3. 组装成数据
    * */
    public ResultEntity inChart(@RequestParam("beginTimeFormat") String beginTimeFormat, @RequestParam("endTimeFormat") String endTimeFormat){

        List<MaterialHistoryStatisticsEntity> records= materialHistoryService.list(new LambdaQueryWrapper<MaterialHistoryStatisticsEntity>()
                .eq(MaterialHistoryStatisticsEntity::getDelFlag,0)
                .orderByDesc(MaterialHistoryStatisticsEntity::getUpdateTime));

        List<MaterialEntity> todayRecords = materialService.list(new LambdaQueryWrapper<MaterialEntity>()
                .eq(MaterialEntity::getDelFlag,0));

        var timeFormats = getTimeFormat(beginTimeFormat, endTimeFormat);
        HashMap<String, Object> xAxis = new HashMap<>();
        /*
            1. 组装 yAxis 数据
        * */
        List<HashMap<String, Object>> yAxis = new ArrayList<>();

        List<String> xAxisData = new ArrayList<>(); // 示例数据，实际应根据记录生成

        List<HashMap<String, Object>> series = new ArrayList<>();

        HashMap<String, Integer> materialNames = new HashMap<>();

        //  获取 过去几天的数据 二维数组 存储  name, timeFormat
        HashMap<String, HashMap<String, Integer>> seriesData = new HashMap<>(); // 假设这里填充出库数量
        for (MaterialHistoryStatisticsEntity record : records) {
            xAxisData.add(record.getCreateTime());
            materialNames.put(record.getName(), 1);
            if (!seriesData.containsKey(record.getName())) {
                seriesData.put(record.getName(), new HashMap<>());
            }
            var tempSeriesData = seriesData.get(record.getName());
            tempSeriesData.put(record.getCreateTime(), record.getNum());
        }

        LocalDate today = LocalDate.now();

        // 创建一个DateTimeFormatter用于格式化日期
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 格式化日期为字符串
        String formattedDate = today.format(formatter);


        for (MaterialEntity record : todayRecords) {
            materialNames.put(record.getName(), 1);

            if (!seriesData.containsKey(record.getName())) {
                seriesData.put(record.getName(), new HashMap<>());
            }
            var tempSeriesData = seriesData.get(record.getName());
            tempSeriesData.put(formattedDate, record.getNum());
        }

        var option = new HashMap<>();
        xAxis.put("type", "category");
        xAxis.put("data", timeFormats);  // 横坐标列表

        /*
         *  tempSeries = {"name": "name", "type": "line", data: [1,2,3,4,5]}
         * */
        for (String name : materialNames.keySet()) {
            var tempSeries = new HashMap<String, Object>();
            tempSeries.put("name", name);
            tempSeries.put("type", "line");

            var tempSerialsData = new ArrayList<>();
            for (String timeFormat : timeFormats) {
                if (seriesData.containsKey(name) && seriesData.get(name).containsKey(timeFormat)) {
                    tempSerialsData.add(seriesData.get(name).get(timeFormat));
                } else {
                    tempSerialsData.add(0);
                }
            }

            tempSeries.put("data", tempSerialsData);
            series.add(tempSeries);
        }

        var legend = new HashMap<String, Object>();
        legend.put("data", new ArrayList<>(seriesData.keySet()));
        option.put("legend", legend);
        option.put("series", series);


        var tempyAxis = new HashMap<String, Object>();
        tempyAxis.put("type", "value");
        option.put("yAxis", tempyAxis);

        option.put("xAxis", xAxis);

        return ResultEntity.createSuccess(option);
    }



    @GetMapping("/out/chart")
    @ApiOperation(value = "每天的出库记录图")
    /*
        1. 使用数据库 sumNumByDateAndName 获取每个产品 每天的出库数量
        2. 转换成 2层数组, map["name"]["time_format"] = 10;
        3. 组装成数据
    * */
    public ResultEntity outChart(@RequestParam("beginTimeFormat") String beginTimeFormat, @RequestParam("endTimeFormat") String endTimeFormat){
        List<MaterialLogStatisticsEntity> records=  materialLogService.sumNumByDateAndName(beginTimeFormat, endTimeFormat);
        var timeFormats = getTimeFormat(beginTimeFormat, endTimeFormat);
        HashMap<String, Object> xAxis = new HashMap<>();
        /*
            1. 组装 yAxis 数据
        * */
        List<HashMap<String, Object>> yAxis = new ArrayList<>();

        List<String> xAxisData = new ArrayList<>(); // 示例数据，实际应根据记录生成

        List<HashMap<String, Object>> series = new ArrayList<>();

        HashMap<String, Integer> materialNames = new HashMap<>();

        //  二维数组 存储  name, timeFormat
        HashMap<String, HashMap<String, Integer>> seriesData = new HashMap<>(); // 假设这里填充出库数量
        for (MaterialLogStatisticsEntity record : records) {
            xAxisData.add(record.getTimeFormat());
            materialNames.put(record.getName(), 1);
            if (!seriesData.containsKey(record.getName())) {
                seriesData.put(record.getName(), new HashMap<>());
            }
            var tempSeriesData = seriesData.get(record.getName());
            tempSeriesData.put(record.getTimeFormat(), record.getNum());
        }

        var option = new HashMap<>();
        xAxis.put("type", "category");
        xAxis.put("data", timeFormats);  // 横坐标列表

        /*
        *  tempSeries = {"name": "name", "type": "line", data: [1,2,3,4,5]}
        * */
        for (String name : materialNames.keySet()) {
            var tempSeries = new HashMap<String, Object>();
            tempSeries.put("name", name);
            tempSeries.put("type", "line");

            var tempSerialsData = new ArrayList<>();
            for (String timeFormat : timeFormats) {
                if (seriesData.containsKey(name) && seriesData.get(name).containsKey(timeFormat)) {
                    tempSerialsData.add(seriesData.get(name).get(timeFormat));
                } else {
                    tempSerialsData.add(0);
                }
            }

            tempSeries.put("data", tempSerialsData);
            series.add(tempSeries);
        }

        // option.put("title", "物料消耗趋势图");
        var legend = new HashMap<String, Object>();
        legend.put("data", new ArrayList<>(seriesData.keySet()));
        option.put("legend", legend);
        option.put("series", series);


        var tempyAxis = new HashMap<String, Object>();
        tempyAxis.put("type", "value");
        option.put("yAxis", tempyAxis);

        option.put("xAxis", xAxis);

        return ResultEntity.createSuccess(option);
    }


    public List<String> getTimeFormat(String beginTimeFormat, String endTimeFormat ) {

        List<String> ans = new ArrayList<>();

        if (beginTimeFormat.compareTo(endTimeFormat) > 0) {
            return ans;
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 指定起始日期
        LocalDate startDate = LocalDate.parse(endTimeFormat, formatter);

        for (int i = 0; i < 7; i++) {
            LocalDate previousDay = startDate.minusDays(i);
            String formattedDate = previousDay.format(formatter);

            if (formattedDate.compareTo(beginTimeFormat) < 0) {
                break;
            }
            ans.add(formattedDate);
        }

        return ans;
    }

    static class chartQuery {
        @ApiModelProperty(value = "begin_time_format")
        String beginTimeFormat ;

        @ApiModelProperty(value = "end_time_format")
        String endTimeFormat ;
    }

    @GetMapping("/out/delete")
    @ApiOperation(value = "删除材料字典列表")
    public ResultEntity deleteOutbound(@RequestParam("id") Long id){
        MaterialEntity entity = new MaterialEntity();
        entity.setId(id);
        entity.setDelFlag(1);
        materialService.updateById(entity);
        return ResultEntity.createSuccess();
    }

    @PostMapping("/dict/add")
    @ApiOperation(value = "新增材料字典")
    public ResultEntity add(@RequestBody MaterialEntity params){

        params.setCreateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setUpdateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setCreator(SecurityUtils.getLoginUser().getUser().getName());
        materialService.saveOrUpdate(params);
        return ResultEntity.createSuccess();
    }


    @GetMapping("/getById/{id}")
    @ApiOperation(value = "获取材料字典")
    public ResultEntity getById(@PathVariable Integer id){

        var ans = materialService.list(new LambdaQueryWrapper<MaterialEntity>()
                .eq(MaterialEntity::getDelFlag,0).eq(MaterialEntity::getId, id)
                .orderByDesc(CommonEntity::getUpdateTime));

        return ResultEntity.createSuccess(ans);
    }


    @GetMapping("/list")
    @ApiOperation(value = "获取材料字典列表")
    public ResultEntity list(PageQuery pageQuery){
        PageUtil.startPage(pageQuery);
        return ResultEntity.createSuccess(PageUtil.getPageList(materialService.list(new LambdaQueryWrapper<MaterialEntity>()
                .eq(MaterialEntity::getDelFlag,0)
                .orderByDesc(CommonEntity::getUpdateTime))));
    }

    /*
        public ResultEntity add(@PathVariable Long id) {

    }
    * */

    @GetMapping("/delete")
    @ApiOperation(value = "删除材料字典列表")
    public ResultEntity delete(@RequestParam("id") Long id){
        MaterialEntity entity = new MaterialEntity();
        entity.setId(id);
        entity.setDelFlag(1);
        materialService.updateById(entity);
        return ResultEntity.createSuccess();
    }


    @PostMapping("/report/add")
    @ApiOperation(value = "新增物料验收检验批次")
    public ResultEntity addReport(@RequestBody MaterialReportEntity params){

        params.setCreateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setUpdateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setCreator(SecurityUtils.getLoginUser().getUser().getName());
        params.setCreateTime(new Date());
        params.setUpdateTime(new Date());
        materialReportService.saveOrUpdate(params);
        return ResultEntity.createSuccess();
    }


    @GetMapping("/report/list")
    @ApiOperation(value = "物料验收检验批次列表")
    public ResultEntity listReport(PageQuery pageQuery){
        PageUtil.startPage(pageQuery);
        return ResultEntity.createSuccess(PageUtil.getPageList(materialReportService.list(new LambdaQueryWrapper<MaterialReportEntity>()
                .eq(MaterialReportEntity::getDelFlag,0)
                .orderByDesc(CommonEntity::getUpdateTime))));
    }
    /*
    * */
    @GetMapping("/report/delete")
    @ApiOperation(value = "删除新增物料验收检验批次")
    public ResultEntity deleteReport(@RequestParam("id") Long id){
        MaterialReportEntity entity = new MaterialReportEntity();
        entity.setId(id);
        entity.setDelFlag(1);
        materialReportService.updateById(entity);
        return ResultEntity.createSuccess();
    }

    @PostMapping("/material/add")
    @ApiOperation(value = "材料入库")
    public ResultEntity addMaterial(@RequestBody MaterialEntity params){

        params.setCreateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setUpdateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setCreator(SecurityUtils.getLoginUser().getUser().getName());
        materialService.saveOrUpdate(params);
        return ResultEntity.createSuccess();
    }


    @PostMapping("/material/sub")
    @ApiOperation(value = "物料出库")
    public ResultEntity deleteMaterial(@RequestBody MaterialEntity params){

        params.setCreateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setUpdateBy(SecurityUtils.getLoginUser().getUser().getId());
        params.setCreator(SecurityUtils.getLoginUser().getUser().getName());
        materialService.saveOrUpdate(params);
        return ResultEntity.createSuccess();
    }



}
